package cc.vv.lkbasecomponent.base.ui;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.IdRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils;
import android.view.View;

import java.lang.ref.WeakReference;
import java.util.ArrayList;

import cc.vv.lkbasecomponent.R;
import cc.vv.lkbasecomponent.base.app.LKBaseApplication;
import cc.vv.lkbasecomponent.base.service.ConnectChangeService;
import cc.vv.lkbasecomponent.base.ui.loading.InterLoading;
import cc.vv.lkbasecomponent.base.ui.loading.LKBaseLoading;
import cc.vv.lkbasecomponent.http.lib.CallBack;
import cc.vv.lkbasecomponent.http.lib.wrap.LKCall;
import cc.vv.lkbasecomponent.util.LKSystemUtil;
import cc.vv.lklibrary.anno.NPFInject;
import cc.vv.lklibrary.log.LogOperate;

/**
 * 基类Activity
 */
public abstract class LKBaseActivity extends AppCompatActivity {
    /**
     * 没网状态
     */
    public static final int NET_TYPE_NONE = ConnectChangeService.TYPE_NONE;
    /**
     * WIFI状态
     */
    public static final int NET_TYPE_WIFI = ConnectChangeService.TYPE_WIFI;
    /**
     * 移动流量状态
     */
    public static final int NET_TYPE_MOBILE = ConnectChangeService.TYPE_MOBILE;

    /**
     * 存放广播接收器，onDestroy中，会把list中的广播取消注册，清空。
     */
    private ArrayList<BroadcastReceiver> mBroadcastReceivers;

    /**
     * 防止内存泄漏 的handler
     */
    private WeakHandler mWeakHandler;

    /**
     * loadingView
     */
    private InterLoading mLoadingView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        NPFInject.getInstance().inject(this);

        init();

        Intent intent = getIntent();
        Bundle data = null;
        if (intent != null) {
            data = intent.getExtras();
        }
        initView(data);
        initData(data);
        initAction(data);

        getLoading().addPierceViews(initLoadingPierceViews());
        getLoading().setCanPierce(initCanPierce());
    }

    /**
     * 初始化
     */
    private void init() {
        if (isWatchConnectionChange() && LKBaseApplication.isConnectionRegister) {
            //只有此界面需要监听并且application中已经启动网络监听,才进行注册网络改变监听广播
            lkRegisterReceiver(true, new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    if (LKSystemUtil.isAppOnForeground()) {
                        //只在前台才通知回调
                        int netType = intent.getIntExtra(ConnectChangeService.TYPE_KEY, 0);
                        if (netType != 0) {
                            onNetChanged(netType);
                        }
                    }
                }
            }, ConnectChangeService.NET_CHANGE_ACTION);
        }
        getLoading().initLoadingView(this);
    }

    /**
     * 网络状态改变回调方法
     *
     * @param netType NET_TYPE_NONE:没网 NET_TYPE_MOBILE:移动流量 NET_TYPE_WIFI:wifi
     */
    protected void onNetChanged(int netType) {
    }

    /**
     * 可重写方法。是否开启网络改变监听。注意：前提是application中需要调用开启网络监听器{@link LKBaseApplication#openConnectChangeReceiver()}
     * <br>默认返回false
     *
     * @return true:此界面接收网络改变通知。 false：此界面不接受网络改变通知。
     */
    protected boolean isWatchConnectionChange() {
        return false;
    }

    /**
     * 初始化view
     *
     * @param data intent传过来的数据
     */
    protected abstract void initView(@Nullable Bundle data);

    /**
     * 初始化数据
     *
     * @param data intent传过来的数据
     */
    protected void initData(@Nullable Bundle data) {
    }


    /**
     * 初始化事件
     *
     * @param data intent传过来的数据
     */
    protected void initAction(@Nullable Bundle data) {
    }

    /**
     * handle防内存泄漏Handler数据
     *
     * @param msg 消息
     */
    protected void onHandleMsg(Message msg) {
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mBroadcastReceivers != null && !mBroadcastReceivers.isEmpty()) {
            for (BroadcastReceiver receiver : mBroadcastReceivers) {
                if (receiver != null) {
                    unregisterReceiver(receiver);
                }
            }
            mBroadcastReceivers.clear();
            mBroadcastReceivers = null;
        }

        if (mWeakHandler != null) {
            mWeakHandler.removeCallbacksAndMessages(null);
            mWeakHandler = null;
        }

    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        /** 屏幕旋转监听*/
        try {
            if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
                LogOperate.i("当前为横屏");
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            } else {
                LogOperate.i("当前为竖屏");
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
            }
        } catch (Exception e) {
            LogOperate.e(e.getMessage());
        }
    }


    /******************************简化相关方法START********************************/
    /***************************************************************************/


    /**
     * 获取防内存泄漏Handler
     *
     * @return 防内存泄漏的Handler
     */
    public final synchronized WeakHandler getHandler() {
        if (mWeakHandler == null) {
            mWeakHandler = new WeakHandler(this);
        }
        return mWeakHandler;
    }

    /**
     * 添加fragment到指定id
     *
     * @param containerViewId 放fragment的控件
     * @param fragment        Fragment
     * @param tag             标识
     */
    public final void addFragment(@IdRes int containerViewId, Fragment fragment, @Nullable String tag) {
        try {
            FragmentManager supportFragmentManager = getSupportFragmentManager();
            FragmentTransaction fragmentTransaction = supportFragmentManager.beginTransaction();
            fragmentTransaction.add(containerViewId, fragment, tag);
            fragmentTransaction.commitNowAllowingStateLoss();
        } catch (Exception e) {
            LogOperate.e(e.getMessage());
        }
    }

    /**
     * activity跳转方法
     *
     * @param activityClass 要跳转的activity.class
     * @param bundle        传递数据
     */
    public final void lkStartActivity(@NonNull Class<? extends Activity> activityClass, @Nullable Bundle bundle) {
        if (activityClass == null) {
            LogOperate.e("跳转界面失败,跳转Activity.class 为空!");
            return;
        }
        Intent intent = new Intent(this, activityClass);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        startActivity(intent);
    }

    /**
     * activity for result 跳转方法
     *
     * @param activityClass
     * @param requestCode
     * @param bundle
     */
    public final void lkStartActivityForResult(@NonNull Class<? extends Activity> activityClass, int requestCode, @Nullable Bundle bundle) {
        if (activityClass == null) {
            LogOperate.e("跳转界面失败,跳转Activity.class 为空!");
            return;
        }
        Intent intent = new Intent(this, activityClass);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        startActivityForResult(intent, requestCode);
    }

    /**
     * 发送广播 方法
     *
     * @param action
     * @param bundle
     */
    public final void lkSendBroadcast(String action, Bundle bundle) {
        if (TextUtils.isEmpty(action)) {
            LogOperate.e("发送广播失败,action 为空!");
            return;
        }
        Intent intent = new Intent(action);
        if (bundle != null) {
            intent.putExtras(bundle);
        }
        sendBroadcast(intent);
    }

    /**
     * 注册广播接收器
     *
     * @param isSelfDestroy true：在onDestroy时，框架帮你取消注册广播。false：自己来
     * @param actions
     * @param receiver
     */
    public final void lkRegisterReceiver(boolean isSelfDestroy, BroadcastReceiver receiver, String... actions) {
        if (actions == null || actions.length <= 0) {
            LogOperate.e("注册广播失败,action 为空!");
            return;
        }
        if (isSelfDestroy) {
            //好吧，由框架在destroy时，帮你取消注册广播.将广播放到list中。
            if (mBroadcastReceivers == null) {
                mBroadcastReceivers = new ArrayList<>(3);
            }
            if (receiver != null && !mBroadcastReceivers.contains(receiver)) {
                mBroadcastReceivers.add(receiver);
            }
        }
        IntentFilter intentFilter = new IntentFilter();
        for (String action : actions) {
            intentFilter.addAction(action);
        }
        registerReceiver(receiver, intentFilter);
    }

    /***************************************************************************/
    /******************************简化相关方法END********************************/
    /***************************************************************************/


    /***************************************************************************/
    /******************************网络相关方法START********************************/
    /***************************************************************************/
    /**
     * 重写此方法，来自定义Loading
     *
     * @return
     */
    public InterLoading getLoading() {
        if (mLoadingView == null) {
            mLoadingView = new LKBaseLoading(R.layout.view_base_loading);
        }
        return mLoadingView;
    }

    /**
     * 重写此方法，返回可穿透点击的views。也可以主动调用loading添加views方法。
     *
     * @return
     */
    protected View[] initLoadingPierceViews() {
        return null;
    }

    /**
     * 重写此方法，返回是否可 触摸 穿透loading层。也可以主动调用loading 方法去实时设置。
     *
     * @return
     */
    protected boolean initCanPierce() {
        return false;
    }

    /**
     * 请求成功回调方法.
     * <br>
     * 也可以重写onSuccess()回调
     *
     * @param url 请求的地址
     * @param obj 返回的实体类
     */
    protected void onRequestSuccess(String url, Object obj) {
    }

    /**
     * 请求开始回调
     *
     * @param url
     * @param isLoading
     */
    protected void onRequestStart(String url, boolean isLoading) {
        InterLoading loading = getLoading();
        if (loading != null && isLoading) {
            loading.showLoading();
        }
    }

    /**
     * 请求结束回调
     *
     * @param resultCode 1:成功，0：cancel，-1：失败
     */
    protected void onRequestFinish(String url, int resultCode, boolean isLoading) {
        InterLoading loadingManager = getLoading();
        if (loadingManager != null && isLoading) {
            loadingManager.closeLoading();
        }
    }

    /**
     * 请求失败回调
     *
     * @param url
     * @param isLoading
     * @param exceptionStr
     */
    protected void onRequestFailure(String url, boolean isLoading, String exceptionStr) {
    }

    /**
     * 请求取消回调
     *
     * @param url
     * @param isLoading
     */
    protected void onRequestCancel(String url, boolean isLoading) {
    }

    /**
     * 返回默认callBack。也可以new BaseCallBack() 进行回调重写.
     *
     * @param <T>
     * @return
     */
    public <T> BaseCallBack<T> getDefCallBack() {
        return new BaseCallBack<>(this);
    }

    /**
     * 默认回调。
     *
     * @param <T>
     */
    protected static class BaseCallBack<T> extends CallBack<T> {

        private WeakReference<LKBaseActivity> mRef;

        public BaseCallBack(LKBaseActivity activity) {
            mRef = new WeakReference<>(activity);
        }

        @Override
        public void onSuccess(String url, T obj) {
            if (mRef.get() != null) {
                mRef.get().onRequestSuccess(url, obj);
            }
        }

        @Override
        public void onStart(String url, boolean isLoading) {
            if (mRef.get() != null) {
                mRef.get().onRequestStart(url, isLoading);
            }
        }

        @Override
        public void onFailure(String url, boolean isLoading, String exceptionStr) {
            if (mRef.get() != null) {
                mRef.get().onRequestFailure(url, isLoading, exceptionStr);
            }
        }

        @Override
        public void onCancel(String url, boolean isLoading) {
            if (mRef.get() != null) {
                mRef.get().onRequestCancel(url, isLoading);
            }
        }

        /**
         * @param url        请求url
         * @param resultCode 1:成功，0：cancel，-1：失败
         * @param isLoading  是否展示loading
         */
        @Override
        public void onFinish(String url, int resultCode, boolean isLoading) {
            if (mRef.get() != null) {
                mRef.get().onRequestFinish(url, resultCode, isLoading);
            }
        }

        @Override
        public void onUpLoadProgress(String filePath, int progress) {
        }

        @Override
        public void onDownLoadProgress(String url, String filePath, int progress) {
        }

        @Override
        public void onDownLoadFailure(String url, String filePath) {
        }

        @Override
        public void onDownLoadSuccess(String url, String filePath) {
        }

    }

    /**
     * 结束请求
     *
     * @param call
     */
    public final void cancelCall(LKCall call) {
        if (call != null) {
            call.cancel();
        }
    }

    /***************************************************************************/
    /******************************网络相关方法END******************************/
    /***************************************************************************/
    /**
     * 防止内存泄漏handler
     */
    public final static class WeakHandler extends Handler {

        private WeakReference<LKBaseActivity> mRef;

        public WeakHandler(LKBaseActivity activity) {
            super(Looper.getMainLooper());
            this.mRef = new WeakReference<>(activity);
        }

        /**
         * 获取当前activity
         *
         * @return 当前activity.可能为空
         */
        public LKBaseActivity get() {
            if (mRef != null && mRef.get() != null) {
                return mRef.get();
            }
            return null;
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            LKBaseActivity t = get();
            if (t != null) {
                t.onHandleMsg(msg);
            }
        }

    }
    /***************************************************************************/


}
